<?php
/**
 * Created by IntelliJ IDEA.
 * User: rootciv
 * Date: 18/05/11
 * Time: 12:03
 */
/**
 * @author victor
 * @access private
 * @version 1.0.0
 */
class system_requeriments_array extends ArrayIterator
{
	private $implode_char = ',';
	public function __construct($array = array(),$implode_char = ',')
	{
		$this->implode_char = $implode_char;
		parent::__construct($array);
	}
	public function setImplodeChar($implode_char)
	{
		$this->implode_char = $implode_char;
	}
	public function __toString()
	{
		//$a = array_keys($this->getArrayCopy());
		return implode($this->implode_char,array_keys($this->getArrayCopy()));
	}
}
/**
 * @author victor
 * @access private
 */
class system_requeriments_php_ini extends ArrayIterator
{
	private $_actual = '';
	private $_symbol = '';
	private $_value = '';
	public function __construct($array = null)
	{
		parent::__construct($array);
		parent::setFlags(ArrayIterator::ARRAY_AS_PROPS);
	}
	public function getData( & $actual, & $symbol, & $value)
	{
		$actual = $this->_actual;
		$symbol = $this->_symbol;
		$value = $this->_value;
	}
	public function validEqual(& $result_bool)
	{
		if(system_requeriments::get_symbol_value($this->current(), $simbolo,$valor))
		{
			$this->_actual = ini_get($this->key());
			$this->_symbol = $simbolo;
			$this->_value = $valor;
			switch(true)
			{
				case $this->_parse_boolean($valor,$_value):
					$this->_parse_boolean( $this->_actual ,$_value2);
						$result_bool = system_requeriments::compare($_value2 ,$simbolo,$_value);
					break;
				case $this->_parse_size_bytes($valor,$_value):
					$this->_parse_size_bytes($this->_actual ,$_value2);
						$result_bool = system_requeriments::compare($_value2 ,$simbolo,$_value);
					break;
				case is_numeric($valor):
						$result_bool = system_requeriments::compare((float) $this->_actual ,$simbolo, (float)$valor);
				default:
						$result_bool = system_requeriments::compare($valor ,$simbolo,$this->_actual);
			}
			return true;
		}
		return false;
	}
	private function _parse_size_bytes($string_bytes,& $bytes)
	{
		list($size,$magnitud)=sscanf($string_bytes, "%d%s");
		if(is_null($size) || is_null($magnitud)){ return false;}
		switch($magnitud)
		{
		        case 't':
		        case 'T':
		        	$size *= 1024;
		        case 'g':
		        case 'G':
		            $size *= 1024;
		        case 'm':
		        case 'M':
		            $size *= 1024;
		        case 'k':
		        case 'K':
		            $size *= 1024;
			            $bytes = $size;
		            break;
          		default:return false;
		    }
		return true;
	}
	private function _parse_boolean($string, &$value)
	{
		switch(strtolower($string))
		{
			case 'off':
			case '0':
			case 'false':
			case null:
			$value = false;break;
			case 'on':
			case '1':
			case 'true':
			$value = true;break;
			default:
			return false;
		}
		return true;

	}
}
/**
 * @author victor
 * @access private
 */
class system_requeriments_extension extends ArrayIterator
{
	public $name_extension_loaded=array();
	public function validEqual(& $result_bool)
	{

		//$result_bool = extension_loaded($this->current());

		if(is_int($this->key()))
		{
			$current = $this->current();
			$result_bool = false;
			if(is_array($current))
			{
				$array = $current;
			}
			else
			{
				$array = explode('||',$current);
			}
			$this->name_extension_loaded = new system_requeriments_array(array(),' , ');
			foreach($array as $extension)
			{
				if(extension_loaded($extension))
				{
					$result_bool = true;
					$this->name_extension_loaded[$extension] = true;
				}
				else
				{
					$this->name_extension_loaded[$extension] = false;
				}
			}
		}
		else
		{
			$result_bool = extension_loaded($this->key()) || extension_loaded($this->current());
		}
		return true;
	}
}
/**
 * @author victor
 * @access private
 */
class system_requeriments_function extends ArrayIterator
{
	public $name_function=array();
	public function validEqual(& $result_bool)
	{
		if(is_int($this->key()))
		{
			$current = $this->current();
			$result_bool = false;
			if(is_array($current))
			{
				$array = $current;
			}
			else
			{
				$array = explode('||',$current);
			}
			$this->name_function =  new system_requeriments_array(array(),' , ');
			foreach($array as $function)
			{
				if(function_exists($function))
				{
					$result_bool = true;$this->name_function[$function] = true;
				}
				else
				{
					$this->name_function[$function] = false;
				}
			}
			return true;
		}
		else
		{
			$result_bool = function_exists($this->key()) || function_exists($this->current());
			return true;
		}
	}
}
/**
 * @author victor
 * @access private
 */
class system_requeriments_class extends ArrayIterator
{
	public $name_class=array();
	public function validEqual(& $result_bool)
	{
		if(is_int($this->key()))
		{
			$current = $this->current();
			$result_bool = false;
			if(is_array($current))
			{
				$array = $current;
			}
			else
			{
				$array =explode('||',$current);
			}
			$this->name_class =  new system_requeriments_array(array(),' , ');
			foreach($array as $cl)
			{
				if(class_exists($cl, true))
				{
					$result_bool = true;
					$this->name_class[$cl] = true;
				}
				else
				{
					$this->name_class[$cl] = false;
				}
			}
		}
		else
		{
			$result_bool = class_exists($this->key(),true) || class_exists($this->current(),true);

		}
		return true;
	}
}
/**
 * @author victor
 * @access private
 */
class system_requeriments_data extends ArrayIterator
{
	private $_actual = '';
	private $_symbol = '';
	private $_value = '';
	private $_path = './';
	private $_exist_data = false;
	public function setPath($path)
	{
		$this->_path = $path;
	}
	public function __construct($array = null)
	{
		parent::__construct($array);
		parent::setFlags(ArrayIterator::ARRAY_AS_PROPS);
	}
	private function _get_data_json($path,& $version)
	{
		$this->_exist_data = true;
		$data = $this->_path . '/' . $path .'/_data.json';
		if(file_exists($data))
		{
			$json = json_decode(file_get_contents($data),true);
			if(isset($json['version']))
			{
				$version = $json['version'];
				$this->_exist_data = true;
				return true;
			}
		}
		else
		{
			$this->_exist_data = false;
		}
		return false;
	}
	public function validEqual(& $result_bool)
	{
		if(system_requeriments::get_symbol_value($this->current(), $simbolo,$valor))
		{
			if($this->_get_data_json($this->key(),$version))
			{
				$this->_actual = $version;
				$this->_symbol = $simbolo;
				$this->_value = $valor;
				$result_bool = system_requeriments::compare_version($version,$simbolo,$valor);
			}
			else
			{
				$this->_value = $valor;
			}
		}
		return false;
	}
	public function getData( & $actual, & $symbol, & $value)
	{
		$actual = $this->_actual;
		$symbol = $this->_symbol;
		$value = $this->_value;
		return $this->_exist_data;
	}
}
/**
 * @author victor
 * @access public
 * @version 1.0
 */
class system_requeriments
{
	/**
	 * @var system_requeriments_php_ini
	 */
	public $php_ini;
	/**
	 * @var \system_requeriments_extension
	 */
	public $extension;
	/**
	 * @var \system_requeriments_function
	 */
	public $function;
	/**
	 * @var \system_requeriments_class
	 */
	public $class;
	/**
	 * @var \system_requeriments_data
	 */
	public $plugin;
	/**
	 * @var \system_requeriments_data
	 */
	public $module;
	/**
	 * @var \system_requeriments_data
	 */
	public $module_admin;
	/**
	 * @var \system_requeriments_data
	 */
	public $component;
	/**
	 * @var \system_requeriments_data
	 */
	public $component_admin;
	public function __construct($file)
	{
		if(file_exists($file))
		{
			$json = json_decode(file_get_contents($file),true);
			if(is_array($json))
			{
				$this->php_ini = new system_requeriments_php_ini(isset($json['php_ini']) ? $json['php_ini'] : array());
				$this->extension = new system_requeriments_extension
						(isset($json['extension']) ? $json['extension'] : array	());

				$this->function =new system_requeriments_function
						( isset($json['function']) ? $json['function'] : array() );
				$this->class = new system_requeriments_class( isset($json['class']) ? $json['class'] : array() );

				$this->plugin = new system_requeriments_data( isset($json['plugin']) ? $json['plugin']:array() );

				$this->module = new system_requeriments_data( isset($json['module']) ? $json['module']:array() );
				$this->module_admin = new system_requeriments_data
						( isset($json['module_admin']) ? $json['module_admin']:array() );
				$this->component = new system_requeriments_data
						( isset($json['component']) ? $json['component']:array() );
				$this->component_admin = new system_requeriments_data
						( isset($json['component_admin']) ? $json['component_admin']:array() );
			}
		}
	}
	static public function get_symbol_value($string,& $symbol,& $value)
	{
		$types = array('<','>','!','=');
		$piezas = str_split($string);
		$symbol = array_shift($piezas);
		if(in_array($symbol,$types))
		{
			if(in_array($piezas[0],$types))
			{
				$symbol .= array_shift($piezas);
			}
		}
		else
		{
			$symbol = '==';
		}
		$value = implode('',$piezas);
		return true;
	}
	static public function compare_version($str1 ,$symbol , $str2 )
	{
		return version_compare($str1,$str2,$symbol);
	}
	static public function compare($str1 ,$symbol , $str2 )
	{
		switch($symbol)
		{
			case '==':
			case '=':
			return $str1 == $str2 ;
			case '<=':
			return $str1 <= $str2 ;
			case '>=':
			return $str1 >= $str2 ;
			case '<':
			return $str1 < $str2 ;
			case '>':
			return $str1 > $str2 ;
			case '<>':
			return $str1 <> $str2 ;
			case '!=':
			return $str1 != $str2 ;
			default:
			return false;
		}
	}

}
/*example
$json = <<<JSON
{
	"php_ini":
		{"allow_url_fopen":"==true",
		"allow_url_include":"==off",
		"arg_separator.input":"==&",
		"max_execution_time":">=30",
		"memory_limit":"<=8m"},
	"extension" : ["curl","ftp","gd","sockets","pdo","pdo_mysql","gettext"],
	"function" : ["file_get_contents||fopen","file_put_contents","json_encode"],
	"class" : ["simplexmlelement","myFile||myXml","PDO","DB","ZipArchive"],
	"module" : [],
	"component" : ["chat"],
	"component_admin" : [],
	"plugin" : []
}

JSON;
echo '<pre>';
class t extends ArrayIterator
{
	public function current()
	{
		echo "<strong>". $this->key() ."</strong>";
		return parent::current();
	}

}
$a = new t();
$a->offsetSet("pedro","perales");
foreach($a as $m)
{

}
echo '</pre>';
*/